Bug 492794 – Pasting external text at end of view yields wrong scrolling
authorPaolo Borelli <pborelli@katamail.com>
Mon, 12 Jan 2009 17:07:35 +0000 (17:07 +0000)
committerPaolo Borelli <pborelli@src.gnome.org>
Mon, 12 Jan 2009 17:07:35 +0000 (17:07 +0000)
2009-01-12  Paolo Borelli  <pborelli@katamail.com>

Bug 492794 – Pasting external text at end of view yields wrong
scrolling to mark

* gtk/gtktextbuffer.[ch]:
* gtk/gtktextview.c:
Add a "paste-done" signal and use it to propelry scroll the
view at the end of the pasted text in the case of an async
paste. Patch by Ignacio Casal Quintero based on a patch by
Yevgen Muntyan.

svn path=/trunk/; revision=22100

ChangeLog
gtk/gtktextbuffer.c
gtk/gtktextbuffer.h
gtk/gtktextview.c

index 296e06548f3fcbb12804b896e1e04c5ab3cbeebe..807bcf394605bdba870ef71987ab86eeb1f8412f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-01-12  Paolo Borelli  <pborelli@katamail.com>
+
+       Bug 492794 – Pasting external text at end of view yields wrong
+       scrolling to mark
+
+       * gtk/gtktextbuffer.[ch]:
+       * gtk/gtktextview.c:
+       Add a "paste-done" signal and use it to propelry scroll the
+       view at the end of the pasted text in the case of an async
+       paste. Patch by Ignacio Casal Quintero based on a patch by
+       Yevgen Muntyan.
+
 2009-01-12  Tor Lillqvist  <tml@iki.fi>
 
        * gdk/gdk.c (gdk_arg_debug_cb) (gdk_arg_no_debug_cb): A
index 69a30aece384fc59bfcff35d824767587ad06e7d..8ce3b38a5baff368a1cfe06c640d15d1d8cb1a8e 100644 (file)
@@ -83,6 +83,7 @@ enum {
   REMOVE_TAG,
   BEGIN_USER_ACTION,
   END_USER_ACTION,
+  PASTE_DONE,
   LAST_SIGNAL
 };
 
@@ -581,6 +582,27 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                   G_TYPE_NONE,
                   0);
 
+   /**
+   * GtkTextBuffer::paste-done:
+   * @textbuffer: the object which received the signal
+   * 
+   * The paste-done signal is emitted after paste operation has been completed.
+   * This is useful to properly scroll the view to the end of the pasted text.
+   * See gtk_text_buffer_paste_clipboard() for more details.
+   * 
+   * Since: 2.16
+   */ 
+  signals[PASTE_DONE] =
+    g_signal_new (I_("paste_done"),
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GtkTextBufferClass, paste_done),
+                  NULL, NULL,
+                  _gtk_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1,
+                  GTK_TYPE_CLIPBOARD);
+
   g_type_class_add_private (object_class, sizeof (GtkTextBufferPrivate));
 }
 
@@ -3301,6 +3323,13 @@ post_paste_cleanup (ClipboardRequest *request_data)
     }
 }
 
+static void
+emit_paste_done (GtkTextBuffer *buffer,
+                 GtkClipboard  *clipboard)
+{
+  g_signal_emit (buffer, signals[PASTE_DONE], 0, clipboard);
+}
+
 static void
 free_clipboard_request (ClipboardRequest *request_data)
 {
@@ -3338,6 +3367,8 @@ clipboard_text_received (GtkClipboard *clipboard,
       
       if (request_data->interactive) 
        gtk_text_buffer_end_user_action (buffer);
+
+      emit_paste_done (buffer, clipboard);
     }
 
   free_clipboard_request (request_data);
@@ -3448,6 +3479,8 @@ clipboard_rich_text_received (GtkClipboard *clipboard,
       if (request_data->interactive)
         gtk_text_buffer_end_user_action (request_data->buffer);
 
+      emit_paste_done (request_data->buffer, clipboard);
+
       if (retval)
         {
           post_paste_cleanup (request_data);
@@ -3462,7 +3495,8 @@ clipboard_rich_text_received (GtkClipboard *clipboard,
 }
 
 static void
-paste_from_buffer (ClipboardRequest  *request_data,
+paste_from_buffer (GtkClipboard      *clipboard,
+                   ClipboardRequest  *request_data,
                    GtkTextBuffer     *src_buffer,
                    const GtkTextIter *start,
                    const GtkTextIter *end)
@@ -3495,6 +3529,8 @@ paste_from_buffer (ClipboardRequest  *request_data,
   if (request_data->interactive) 
     gtk_text_buffer_end_user_action (buffer);
 
+  emit_paste_done (buffer, clipboard);
+
   g_object_unref (src_buffer);
 
   free_clipboard_request (request_data);
@@ -3518,13 +3554,13 @@ clipboard_clipboard_buffer_received (GtkClipboard     *clipboard,
        {
          gtk_text_buffer_get_bounds (src_buffer, &start, &end);
 
-         paste_from_buffer (request_data, src_buffer,
+         paste_from_buffer (clipboard, request_data, src_buffer,
                             &start, &end);
        }
       else
        {
          if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
-           paste_from_buffer (request_data, src_buffer,
+           paste_from_buffer (clipboard, request_data, src_buffer,
                               &start, &end);
        }
     }
index fd1131410a6dba52a541d5a714072189831cefe5..d160c49065381ea4ea03cd77af9be0cf4ce6a235 100644 (file)
@@ -143,13 +143,15 @@ struct _GtkTextBufferClass
   void (* begin_user_action)  (GtkTextBuffer *buffer);
   void (* end_user_action)    (GtkTextBuffer *buffer);
 
+  void (* paste_done)         (GtkTextBuffer *buffer,
+                               GtkClipboard  *clipboard);
+
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
   void (*_gtk_reserved3) (void);
   void (*_gtk_reserved4) (void);
   void (*_gtk_reserved5) (void);
-  void (*_gtk_reserved6) (void);
 };
 
 GType        gtk_text_buffer_get_type       (void) G_GNUC_CONST;
index 1ec7b0248c2144b5ce34a7f2a4fdd380f237940a..dc8126099c7d48b8d02fcc6b0ba538516b5cf11c 100644 (file)
@@ -329,6 +329,9 @@ static void gtk_text_view_mark_set_handler       (GtkTextBuffer     *buffer,
 static void gtk_text_view_target_list_notify     (GtkTextBuffer     *buffer,
                                                   const GParamSpec  *pspec,
                                                   gpointer           data);
+static void gtk_text_view_paste_done_handler     (GtkTextBuffer     *buffer,
+                                                  GtkClipboard      *clipboard,
+                                                  gpointer           data);
 static void gtk_text_view_get_cursor_location    (GtkTextView       *text_view,
                                                  GdkRectangle      *pos);
 static void gtk_text_view_get_virtual_cursor_pos (GtkTextView       *text_view,
@@ -1384,6 +1387,9 @@ gtk_text_view_set_buffer (GtkTextView   *text_view,
       g_signal_handlers_disconnect_by_func (text_view->buffer,
                                             gtk_text_view_target_list_notify,
                                             text_view);
+      g_signal_handlers_disconnect_by_func (text_view->buffer,
+                                            gtk_text_view_paste_done_handler,
+                                            text_view);
       g_object_unref (text_view->buffer);
       text_view->dnd_mark = NULL;
       text_view->first_para_mark = NULL;
@@ -1425,6 +1431,9 @@ gtk_text_view_set_buffer (GtkTextView   *text_view,
       g_signal_connect (text_view->buffer, "notify::paste-target-list",
                        G_CALLBACK (gtk_text_view_target_list_notify),
                         text_view);
+      g_signal_connect (text_view->buffer, "paste-done",
+                       G_CALLBACK (gtk_text_view_paste_done_handler),
+                        text_view);
 
       gtk_text_view_target_list_notify (text_view->buffer, NULL, text_view);
 
@@ -5702,9 +5711,16 @@ gtk_text_view_paste_clipboard (GtkTextView *text_view)
                                   clipboard,
                                   NULL,
                                   text_view->editable);
+}
+
+static void
+gtk_text_view_paste_done_handler (GtkTextBuffer *buffer,
+                                  GtkClipboard  *clipboard,
+                                  gpointer       data)
+{
+  GtkTextView *text_view = data;
   DV(g_print (G_STRLOC": scrolling onscreen\n"));
-  gtk_text_view_scroll_mark_onscreen (text_view,
-                                      gtk_text_buffer_get_insert (get_buffer (text_view)));
+  gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_buffer_get_insert (buffer));
 }
 
 static void